#include <string.h>

#include <vector>
#include <iostream>
using std::cout;
using std::endl;
using std::vector;

class String 
{
public:
	String();
	String(const char *);
	String(const String &);
	~String();
	String &operator=(const String &);
	String &operator=(const char *);

	String &operator+=(const String &);
	String &operator+=(const char *);
	
	char &operator[](std::size_t index);
	const char &operator[](std::size_t index) const;
	
	std::size_t size() const;
	const char* c_str() const;
	
	friend bool operator==(const String &, const String &);
	friend bool operator!=(const String &, const String &);
	
	friend bool operator<(const String &, const String &);
	friend bool operator>(const String &, const String &);
	friend bool operator<=(const String &, const String &);
	friend bool operator>=(const String &, const String &);
	
	friend std::ostream &operator<<(std::ostream &os, const String &s);
	friend std::istream &operator>>(std::istream &is, String &s);

private:
	char * _pstr;
};

String operator+(const String &, const String &);
String operator+(const String &, const char *);
String operator+(const char *, const String &);

String::String()
: _pstr(nullptr)
{
}

String::String(const char *str)
{
	_pstr = new char[strlen(str) + 1]();
	strcpy(_pstr, str);
}
String::String(const String &str)
{
	_pstr = new char[str.size()+1]();
	strcpy(_pstr, str._pstr);
}

// 析构函数
String::~String()
{
	if (_pstr)
	{
		delete[] _pstr;
		_pstr = nullptr;
	}
}

// 赋值符号
String &String::operator=(const String &str)
{
    if(this != &str)
    {
		delete[] _pstr;
		_pstr = new char[str.size()+1]();
		strcpy(_pstr, str._pstr);
    }
    return *this;

#if 0
	if (_pstr)
	{
	}
	else
	{
		_pstr = new char[str.size()+1]();
		strcpy(_pstr, str._pstr);
	}
	return *this;
#endif
}

String &String::operator=(const char *str)
{
    String tmp(str);
    *this = tmp;
    return *this;

#if 0
	if (_pstr)
	{
		delete[] _pstr;
		_pstr = new char[strlen(str) + 1]();
		strcpy(_pstr, str);
	}
	else
	{
		_pstr = new char[strlen(str)+1]();
		strcpy(_pstr, str);
	}
	return *this;
#endif
}

// 加等于符号
String &String::operator+=(const String &str)
{
	if(this==&str) return *this;
	if (this->_pstr)
	{
		char *tmp = _pstr;
		_pstr = new char[strlen(tmp) + str.size()+1]();
		strcpy(_pstr, tmp);
		strcat(_pstr, str._pstr);
		delete[] tmp;
	}
	else
	{
		_pstr = new char[str.size()+1]();
		strcpy(_pstr, str._pstr);
	}

	return *this;
}
String &String::operator+=(const char *str)
{
    String tmp(str);
    *this += tmp;
    return *this;
#if 0
	if (this->_pstr)
	{
		char *tmp = _pstr;
		_pstr = new char[strlen(tmp) + strlen(str)+1]();
		strcpy(_pstr, tmp);
		strcat(_pstr, str);
		delete[] tmp;
	}
	else
	{
		_pstr = new char[strlen(str)+1]();
		strcpy(_pstr, str);
	}

	return *this;
#endif
}

//[]访问运算符
char &String::operator[](std::size_t index)
{
	return _pstr[index];
}

const char &String::operator[](std::size_t index) const
{
	return _pstr[index];
}

// 字符串大小
std::size_t String::size() const
{
	return strlen(_pstr);
}

// 返回另一串c风格字符串
const char *String::c_str() const
{
	//char *str = new char[strlen(_pstr) + 1]();
	//strcpy(str, _pstr);
	//return str;
    return _pstr;
}

// 字符串比较运算符
bool operator==(const String &str1, const String &str2)
{
	return strcmp(str1._pstr, str2._pstr)==0;
}
bool operator!=(const String &str1, const String &str2)
{
	return !(strcmp(str1._pstr, str2._pstr) == 0);
}

bool operator<(const String &str1, const String &str2)
{
	if (strcmp(str1._pstr, str2._pstr) < 0)
		return true;
	else
		return false;
}

bool operator>(const String &str1, const String &str2)
{
	if (strcmp(str1._pstr, str2._pstr) > 0)
		return true;
	else
		return false;
}
bool operator<=(const String &str1, const String &str2)
{
	if (strcmp(str1._pstr, str2._pstr) <= 0)
		return true;
	else
		return false;
}
bool operator>=(const String &str1, const String &str2)
{
	if (strcmp(str1._pstr, str2._pstr) >= 0)
		return true;
	else
		return false;
}
// String的输入输出功能
std::ostream &operator<<(std::ostream &os, const String &s)
{
	if(s._pstr)
		os << s._pstr << endl;
	return os;
}

std::istream &operator>>(std::istream &is, String &s)
{
    vector<char> buff;
    buff.reserve(1024);
    char ch;
    while((ch = is.get()), ch !='\n'){
        buff.push_back(ch);
    }
    if(s._pstr) {
        delete [] s._pstr;
    }
	s._pstr = new char[buff.size() + 1]();
	//strcpy(s._pstr, &*buff.begin());
	strcpy(s._pstr, buff.data());
    return is;
#if 0
	char buff[1024] = {0};
	is >> buff;
	if (s._pstr)
	{
		delete[] s._pstr;
		s._pstr = new char[strlen(buff) + 1]();
		strcpy(s._pstr, buff);
	}
	else
	{
		s._pstr = new char[strlen(buff) + 1]();
		strcpy(s._pstr, buff);
	}
	return is;
#endif
}

//出现重复的代码时，要想到进行复用
String operator+(const String &str1, const String &str2)
{
    String tmp(str1);
    tmp += str2;
    return tmp;

#if 0
	int len = str1.size() + str2.size();
	String str;
	str._pstr = new char[len+1]();
	strcat(str._pstr, str1._pstr);
	strcat(str._pstr, str2._pstr);
	return str;
#endif
}
String operator+(const String &str1, const char *cstr)
{
    String tmp(cstr);
    return str1 + tmp;
#if 0
	int len = str1.size() + strlen(cstr);
	String str;
	str._pstr = new char[len+1]();
	strcat(str._pstr, str1._pstr);
	strcat(str._pstr, cstr);
	return str;
#endif
}
String operator+(const char *cstr, const String &str1)
{
    String tmp(cstr);
    return tmp + str1;

#if 0
	int len = str1.size() + strlen(cstr);
	String str;
	str._pstr = new char[len+1]();
	strcat(str._pstr, cstr);
	strcat(str._pstr, str1._pstr);
	return str;
#endif
}


int main()
{
    String s1("hello");
    s1 += s1;
}
